#include "functions.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>






/**
 * returns if program was started interactively
 */
int is_interactive() {
	static int result = -1;
	if (result < 0) {
		struct stat *stat = (struct stat *)calloc(sizeof(struct stat), 1);
		int fd = STDIN_FILENO;
		fstat(fd, stat);
		result = S_ISCHR(stat->st_mode);
	}
	return result;
}




/**
 * gets N (number of bytes) and coverts to  human-readable string.
 *    1'024 --> "1024B"
 *    1'050 --> "1.02K"
 *   35'000 --> "34.2K"
 */
char *format_size(long n){
	static char *format_size_buf = NULL;
	char *buf;
	if ( !(buf = format_size_buf) ) {
		buf = (char *)malloc(50 * sizeof(char));
		format_size_buf = buf;
	}
	
	double b = n;
	double k = 1. * b / 1024;
	double m = 1. * k / 1024;
	double g = 1. * m / 1024;
	
	     if (g >= 1.01) sprintf(buf, "%.1fG", g);
	else if (m >= 100)  sprintf(buf, "%.0fM", m);
	else if (m >= 10)   sprintf(buf, "%.1fM", m);
	else if (m >= 1.01) sprintf(buf, "%.2fM", m);
	else if (k >= 100)  sprintf(buf, "%.0fK", k);
	else if (k >= 10)   sprintf(buf, "%.1fK", k);
	else if (k >= 1.01) sprintf(buf, "%.2fK", k);
	else                sprintf(buf, "%.0fB", b);
	return buf;
}


/**
 * returns if program was started interactively
 */
char *read_stream(FILE *f, long *sz){
    char *buf=NULL;
    long n=0;
    while(!feof(f)) {
        if(!(buf = (char *)realloc(buf, n + READ_CHUNK_SIZE + 1))){
            perror("realloc");
            exit(1);
        }
        n += fread(buf+n, 1, READ_CHUNK_SIZE, f);
    }
    buf[n]=0;
    if(sz)
    	*sz=n;
    return buf;
}


/**
 * returns if program was started interactively
 */
unsigned int *gen_primes(unsigned int n_max){
	unsigned int *primes;
	unsigned int n=0, p=2, m, m_max;
	primes = (unsigned int *)calloc(n_max, sizeof(unsigned int));
	for(n=0; n<=n_max; ++n) {
next_m:
		m_max = floor(sqrt(p++))+1;
		for (m=0; (m<n) && (m<=m_max); ++m)
			if(!(p%primes[m]))
				goto next_m;
		primes[n]=p;
	}
	return primes;
}




